This section describes the remaining loop clauses.
with var =
value
(loop with x = 17 do ...)
(let ((x 17)) (loop do ...))
(loop for x = 17 then x do ...)
Naturally, the variable var might be used for some purpose in the rest of the loop. For example:
(loop for x in my-list with res = nil do (push x res)
finally return res)
This loop inserts the elements of my-list at
the front of a new list being accumulated in
res, then returns the list res at
the end of the loop. The effect is similar to that of a
collect clause, but the list gets reversed by
virtue of the fact that elements are being pushed onto the
front of res rather than the end.
If you omit the = term, the variable is
initialized to nil. (Thus the
‘= nil’ in
the above example is unnecessary.)
Bindings made by with are sequential by
default, as if by let*. Just like
for clauses, with clauses can be
linked with and to cause the bindings to be made
by let instead.
if condition clausedo,
return, if, or unless
clause. Several clauses may be linked by separating them with
and. These clauses may be followed by
else and a clause or clauses to execute if the
condition was false. The whole construct may optionally be
followed by the word end (which may be used to
disambiguate an else or and in a
nested if).
The actual non-nil value of the condition
form is available by the name it in the
“then” part. For example:
(setq funny-numbers '(6 13 -1))
⇒ (6 13 -1)
(loop for x below 10
if (oddp x)
collect x into odds
and if (memq x funny-numbers) return (cdr it) end
else
collect x into evens
finally return (vector odds evens))
⇒ [(1 3 5 7 9) (0 2 4 6 8)]
(setq funny-numbers '(6 7 13 -1))
⇒ (6 7 13 -1)
(loop <same thing again>)
⇒ (13 -1)
Note the use of and to put two clauses into
the “then” part, one of which is itself an
if clause. Note also that end,
while normally optional, was necessary here to make it clear
that the else refers to the outermost
if clause. In the first case, the loop returns a
vector of lists of the odd and even values of x.
In the second case, the odd number 7 is one of the
funny-numbers so the loop returns early; the
actual returned value is based on the result of the
memq call.
when condition
clauseif.unless condition
clauseunless clause is just like if
except that the sense of the condition is reversed.named namenil to the
implicit block surrounding the loop. The name is the
symbol to be used as the block name.initially [do]
forms...for or with
have been bound to their initial values).
initially clauses can appear anywhere; if there
are several, they are executed in the order they appear in the
loop. The keyword do is optional.finally [do]
forms...for or
while). initially and
finally clauses may appear anywhere in the loop
construct, but they are executed (in the specified order) at
the beginning or end, respectively, of the loop.finally return formcollect or return,
the loop will simply return nil.) Variables bound
by for, with, or into
will still contain their final values when form is
executed.do forms...do may be followed by any number of
Lisp expressions which are executed as an implicit
progn in the body of the loop. Many of the
examples in this section illustrate the use of
do.return formloop form. The finally clauses,
if any, are not executed. Of course, return is
generally used inside an if or
unless, as its use in a top-level loop clause
would mean the loop would never get to “loop”
more than once.
The clause ‘return
form’ is equivalent to
‘do (return
form)’ (or
return-from if the loop was named). The
return clause is implemented a bit more
efficiently, though.
While there is no high-level way to add user extensions to
loop (comparable to defsetf for
setf, say), this package does offer two properties
called cl-loop-handler and
cl-loop-for-handler which are functions to be called
when a given symbol is encountered as a top-level loop clause or
for clause, respectively. Consult the source code in
file cl-macs.el for
details.
This package's loop macro is compatible with that
of Common Lisp, except that a few features are not implemented:
loop-finish and data-type specifiers. Naturally, the
for clauses which iterate over keymaps, overlays,
intervals, frames, windows, and buffers are Emacs-specific
extensions.